package com.cpjit.data;

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.deser.std.JsonNodeDeserializer;
import com.fasterxml.jackson.databind.exc.MismatchedInputException;
import com.fasterxml.jackson.databind.node.ArrayNode;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.domain.Sort;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
 * @author yonghuan[cpjit@qq.com]
 * @see Sort
 */
public class SortDeserializer extends JsonDeserializer<Sort> {

    @Override
    public Sort deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
        try {
            ArrayNode arrayNode = (ArrayNode) JsonNodeDeserializer.getDeserializer(ArrayNode.class).deserialize(p, ctxt);
            List<Sort.Order> orders = new ArrayList<>(1);
            for (Iterator<JsonNode> itr = arrayNode.elements(); itr.hasNext(); ) {
                String[] s = itr.next().asText().split(",");
                Sort.Order order = (s.length == 1 || "asc".equalsIgnoreCase(s[1])) ? Sort.Order.by(s[0]) : Sort.Order.desc(s[0]);
                orders.add(order);
            }
            return Sort.by(orders);
        } catch (MismatchedInputException ex) {
            String str = StringUtils.trimToNull(p.getValueAsString());
            if (str == null) {
                return Sort.unsorted();
            }
            // Single empty parameter, e.g "sort="
            String[] sort = str.split(",");
            if (sort.length == 1) {
                return Sort.by(sort[0]);
            }
            return Sort.by(Sort.Direction.fromString(sort[1]), sort[0]);
        }
    }
}
